package com.rookie.im.core.server.utils;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;

import com.alibaba.fastjson2.JSONObject;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rookie.im.core.codec.proto.Message;
import com.rookie.im.core.config.AppConfig;
import com.rookie.im.utils.enums.CommandType;
import com.rookie.im.utils.Constans.RabbitmqConstans;

import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RabbitManager {
	private static final Object lock = new Object();
	private static ConnectionFactory factory = null;
	private static Connection connection = null;
	private static ConcurrentHashMap<String, Channel> channelHashMap = new ConcurrentHashMap<>();
	public static void init(AppConfig.Rabbitmq config) {
		synchronized (lock) {
			factory = new ConnectionFactory();
			factory.setHost(config.getHost());
			factory.setPort(config.getPort());
			factory.setUsername(config.getUsername());
			factory.setPassword(config.getPassword());
			factory.setVirtualHost(config.getVirtualHost());
		}
	}
	
	public static Connection getConnection() {
		synchronized (lock) {
			if (connection == null) {
				try {
					connection = factory.newConnection();
				} catch (IOException | TimeoutException e) {
					throw new RuntimeException(e);
				}
			}
		}
		return connection;
	}
	
	public static Channel getChannel(String name) {
		return channelHashMap.computeIfAbsent(name, key->{
			try {
				return getConnection().createChannel();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		});
	}
	
	public static void publish(Message message) {
		int command = message.getMessageHead().getCommand();
		String channelName = RabbitmqConstans.Im2MessageService;
		switch (CommandType.genCommnadeType(command)) {
			case USER:
				channelName = RabbitmqConstans.Im2UserService;
				break;
			case SYSTEM:
				channelName = RabbitmqConstans.Im2SystemService;
				break;
			case MESSAGE:
				channelName = RabbitmqConstans.Im2MessageService;
			default:
				break;
		}
		try {
			Channel channel = getChannel(channelName);
			JSONObject json = new JSONObject();
			json.put("command", message.getMessageHead().getCommand());
			json.put("appid", message.getMessageHead().getAppId());
			json.put("clientType", message.getMessageHead().getClientType());
			json.put("imei", message.getMessageHead().getImei());
			channel.basicPublish(channelName, "", null, json.toJSONString().getBytes());
			log.info("[{}]push mesg: {}", channelName, json);
		} catch (IOException e) {
			log.error("mq推送异常: {}", e.getMessage());
		}
	}
}
